#include "Serial.hpp"
#include <iostream>
// #include <boost/asio.hpp>
// //#include <boost/bind.hpp>
// //#include <boost/array.hpp>
// #include <boost/asio/steady_timer.hpp>
// #include <memory>
// #include <thread>
// #include <functional>
// #include <queue>
// #include <string.h>
// #include <vector>
Serial::Serial(SerialConfig config)
    : config_(config),
      status_timer_(io_)
{
  
}

Serial::Serial(std::string port,int baud)
    :status_timer_(io_)
{
    config_.baud=baud;
    config_.port=port;
    //interval
}
Serial::~Serial()
{
    if (serial_port_ == nullptr)
        serial_port_->close();
}
void Serial::close()
{
    serial_port_->close();
}

void Serial::open()
{
    try
    {
        if (serial_port_ == nullptr)
            serial_port_ = std::make_shared<serial_port>(io_);

        std::string port = "/dev/" + config_.port;
        std::cout << "connect port: " << port << ", baud: " << config_.baud << std::endl;
        boost::system::error_code ec = serial_port_->open(port, ec_);
        if(ec.value()!=0)
            std::cout << "ec: " << ec.value() << std::endl;

        // 设置串口参数
        serial_port_->set_option(serial_port::baud_rate(config_.baud));
        serial_port_->set_option(serial_port::flow_control(serial_port::flow_control::none));
        serial_port_->set_option(serial_port::parity(serial_port::parity::none));
        serial_port_->set_option(serial_port::stop_bits(serial_port::stop_bits::one));
        serial_port_->set_option(serial_port::character_size(8));
        rec_flag=0;
       // startTask();
    }
    catch (std::exception &err)
    {
         std::cout << "Exception Error: " << err.what() << std::endl;
    }
}
/// @brief 
/// @param buf 
void Serial::write(std::string &buf)
{
    boost::system::error_code ec;
    int size = serial_port_->write_some(boost::asio::buffer(buf), ec);
    if (size == 0)
    {
        serial_port_->close();
        open();
    }
   // std::cout << name_ << " send ec: " << ec.message() << std::endl;
}

void Serial::write(std::vector<u_int8_t> &buf)
{
    boost::system::error_code ec;
    int size = serial_port_->write_some(boost::asio::buffer(buf), ec);
    if (size == 0)
    {
        serial_port_->close();
        open();
    }
   // std::cout << " send ec: " << ec.message() << std::endl;
}
void Serial::read()
{   
    rec_flag=0;
    while (1)
    {
        if (serial_port_ != nullptr && serial_port_->is_open())
        {   
            // serial_rec_v8.clear();
            int size = serial_port_->read_some(boost::asio::buffer(receiveData));
            if(size>0)
            {
                msg_buf_.clear();
                for(int i=0;i<size;i++)msg_buf_.push_back(receiveData[i]);
                // Serial_rec_Callback();
                recvMsg(msg_buf_);
           // printf("receive %d \n",size);
            }
        }
    }
}
void Serial::runThreadFunc()
{
    read_thread_ = std::thread(&Serial::read, this);
    read_thread_.detach();
}
void Serial::startTimer(int ms_s)
{
 interval = std::chrono::milliseconds(ms_s);   
 if (!running) {
            running = true;
            auto thread = std::thread([this]() {
                while (running) {
                //    callback(); // 执行回调
                    if(sendbuf_vect.size()!=0)
                        write(sendbuf_vect);
                    std::this_thread::sleep_for(interval);
                }
            });
            thread.detach(); // 让定时器在后台运行，防止主线程阻塞
        }
}
void Serial::stopTimer()
 {
     running = false;
 }
std::string Serial::toHex(uint8_t ch)
{
    char buf[8] = {0};
    snprintf(buf, 8, "%x", ch);
    return buf;
}
void Serial::display_rec_hex(std::vector<u_int8_t>& msg)
{
    std::stringstream ss;
    for(auto i: msg)
    {
        ss << toHex(i) << " ";
    }
     std::cout << "recv: " << ss.str() << std::endl; 
}

